package cz.vse.po1715.piskorky.sit.sit;

import cz.vse.po1715.piskorky.sit.hra.IHra;
import java.io.*;
import java.net.*;
/**
 *
 * @author Zuzanka
 */
public class Sit implements ISit{
    
    
//== KONSTANTNÍ ATRIBUTY TŘÍDY =================================================
    public final static int VYCHOZI_PORT = 11111;
//== PROMĚNNÉ ATRIBUTY TŘÍDY ===================================================
    private IHra hra;
    private Socket soketKlient;
    private PrintWriter vystup;
//== STATICKÝ INICIALIZAČNÍ BLOK - STATICKÝ KONSTRUKTOR ========================
//== KONSTANTNÍ ATRIBUTY INSTANCÍ ==============================================
//== PROMĚNNÉ ATRIBUTY INSTANCÍ ================================================
//== PŘÍSTUPOVÉ METODY ATRIBUTŮ TŘÍDY ==========================================
//== OSTATNÍ NESOUKROMÉ METODY TŘÍDY ===========================================
//##############################################################################
//== KONSTRUKTORY A TOVÁRNÍ METODY =============================================
//== ABSTRAKTNÍ METODY =========================================================
//== PŘÍSTUPOVÉ METODY INSTANCÍ ================================================

    /***************************************************************************
         * Nastaví odkaz na hru.
         *
         * @param hra
         */
    public final void setHra(IHra hra)
    {
       this.hra = hra;
    }

    /***************************************************************************
         * Nataví socket klienta. Socket je informace o připojení. (ip adresa, port)
         *
         * @param soket
         */
    public void setSoketKlient(Socket soket) {
        this.soketKlient = soket;
        SpustKomunikaci();
    }
    
    @Override
    public void spustServer() {
        Server srv = new Server(VYCHOZI_PORT);
        srv.setSit(this);
        srv.start();
        VypisZpravu("Čekám na portu " + VYCHOZI_PORT);
    }
    
    @Override
    public void pripojSeKServeru(String ipAdresa) {
        try {
            soketKlient = new Socket(ipAdresa, VYCHOZI_PORT);
            SpustKomunikaci();
        } catch (Exception ex) {
            VypisChybu("Nelze se připojit k serveru",ex);
        }
    }
    
    @Override
    public void odesliTah(int x, int y) {
        String stream;
        stream = "Tah:" + x + ";" + y;
        this.odesliStream(stream);
    }
    
    @Override
    public void odesliZpravu(String zprava) {
        String stream;
        stream = "Zprava:" + zprava;
        this.odesliStream(stream);
    }

    /***************************************************************************
         * Zpracuje stream. Tah nebo zpráva.
         * Tah: 10, 20
         * Zprava: Ahoj
         */
    public void zpracujStream(String stream) {
        int index;
        String typ;
        String hodnota;
        index = stream.indexOf(":");
        typ = stream.substring(0, index);
        hodnota = stream.substring(index + 1);
        
        if (typ.equals("Tah")) {
            int x;
            int y;
            String[] tahy;
            tahy = hodnota.split(";");
            
            x = Integer.parseInt(tahy[0]);
            y = Integer.parseInt(tahy[1]);
            
            hra.zpracujTah(x, y);
        }
        
        if (typ.equals("Zprava")) {
            hra.zpracujZpravu(hodnota);
        }
    }
    
//== SOUKROMÉ A POMOCNÉ METODY TŘÍDY ===========================================
   /***************************************************************************
         * Nastaví vstup a výstup k druhému hráči. Vstup je naslouchátko a výstup je stream.
         * 
         * 
         */
    private void SpustKomunikaci() {
      //Vstup
       Naslouchatko naslouchatko = new Naslouchatko(soketKlient);
       naslouchatko.setSit(this);
       naslouchatko.start();
       //Výstup
       try {
            vystup = new PrintWriter(soketKlient.getOutputStream(),true);
            VypisZpravu("Komunikace byla navázána. Hra může začít");
       } catch (Exception ex) {
            VypisChybu("Chyba při navazování komunikace.", ex);
       }
       
       
   }
    
//== SOUKROMÉ A POMOCNÉ METODY INSTANCÍ ========================================
    /***************************************************************************
         * Odešle stream do naslouchátka druhého hráče.
         * 
         * @param steam
         */
    private void odesliStream(String stream) {
       try {
           if (!soketKlient.isConnected()) {
               throw new Exception("Připojení neexistuje");
           }
            vystup.println(stream);
       } catch (Exception ex) {
           VypisChybu("Chyba při odesílání streamu. ", ex);
       }
   }
   
   /***************************************************************************
         * Slouží ke komunikaci s hrou. (systémové informace, chyby)
         * 
         * @param zprava
         */
    private void VypisZpravu(String zprava) {
       hra.vypisZpravu(zprava);
   }

    /***************************************************************************
         * Informace o chybě.
         *
         * @param zprava
         * @param ex
         */
   private void VypisChybu(String zprava, Exception ex) {
       hra.vypisZpravu(zprava + " : " + ex.toString());
   }
   
//== VNOŘENÉ A VNITŘNÍ TŘÍDY ===================================================
//== TESTOVACÍ METODY A TŘÍDY ==================================================
    
    

    
}
